package repository

import (
	"context"
	"encoding/json"
	"gitee.com/flycash/ai-gateway-demo/internal/domain"
	"gitee.com/flycash/ai-gateway-demo/internal/repository/dao"
)

type AsyncTaskRepo interface {
	Save(ctx context.Context, task domain.AsyncTask) error
	GetTaskByID(ctx context.Context, taskId string) (domain.AsyncTask, error)
}

type asyncTaskRepo struct {
	asyncDao dao.AsyncTaskDAO
}

func NewAsyncTaskRepo(asyncDao dao.AsyncTaskDAO) AsyncTaskRepo {
	return &asyncTaskRepo{
		asyncDao: asyncDao,
	}
}

func (a *asyncTaskRepo) Save(ctx context.Context, task domain.AsyncTask) error {
	taskDao, err := a.toDao(task)
	if err != nil {
		return err
	}
	return a.asyncDao.Save(ctx, taskDao)
}

func (a *asyncTaskRepo) GetTaskByID(ctx context.Context, taskId string) (domain.AsyncTask, error) {
	task, err := a.asyncDao.GetTaskByID(ctx, taskId)
	if err != nil {
		return domain.AsyncTask{}, nil
	}
	return a.toView(task)
}

func (a *asyncTaskRepo) toDao(task domain.AsyncTask) (dao.AsyncTask, error) {
	reqJson, err := json.Marshal(task.Req)
	if err != nil {
		return dao.AsyncTask{}, err
	}
	var resp string
	if task.Status != 0 {
		respJson, err := json.Marshal(task.Resp)
		if err != nil {
			return dao.AsyncTask{}, err
		}
		resp = string(respJson)
	}

	ta := dao.AsyncTask{
		TaskID:    task.TaskID,
		AsyncReq:  string(reqJson),
		Status:    task.Status,
		AsyncResp: resp,
	}
	return ta, nil
}

func (a *asyncTaskRepo) toView(task dao.AsyncTask) (domain.AsyncTask, error) {
	domainTask := domain.AsyncTask{
		TaskID: task.TaskID,
		Status: task.Status,
		Ctime:  task.Ctime,
		Utime:  task.Utime,
	}

	if task.AsyncReq != "" {
		var req domain.AsyncRequest
		err := json.Unmarshal([]byte(task.AsyncReq), &req)
		if err != nil {
			return domain.AsyncTask{}, err
		}
		domainTask.Req = req
	}

	if task.AsyncResp != "" {
		var resp domain.SyncResponse
		err := json.Unmarshal([]byte(task.AsyncReq), &resp)
		if err != nil {
			return domain.AsyncTask{}, err
		}
		domainTask.Resp = resp
	}
	return domainTask, nil
}
